Introdução
Esta análise busca investigar um método de cálculo de correlação espacial em R. Consideraremos as estatísticas de autocorrelação espacial global e como identificar agrupamentos espaciais em toda a nossa área de estudo.
A base deste trabalho é a Primeira Lei da Geografia de Tobler: “tudo está relacionado a tudo mais, mas as coisas próximas estão mais relacionadas do que as coisas distantes”.
Assim, usando o conjunto de dados(Dados de Crime Polícia de Los Angeles), veremos se o crime em Los Angeles(Analisado na Comunidade Kaggle) é espacialmente autocorrelacionado e identificamos os clusers usando o LISA (Local Measure of Spatial Association).
Autocorrelação Espacial
rr # Exibindo imagem knitr::include_graphics(./Spatial_Autocorrelation.jpg)

Preparando o ambiente
rr # Setando idioma e local da pasta de trabalho Sys.setlocale(_ALL, _Brazil.1252)
[1] \LC_COLLATE=Portuguese_Brazil.1252;LC_CTYPE=Portuguese_Brazil.1252;LC_MONETARY=Portuguese_Brazil.1252;LC_NUMERIC=C;LC_TIME=Portuguese_Brazil.1252\
rr setwd(:/Analises R/Crime-em-Los-Angeles)
Importando bibliotecas
library(tidyverse) library(classInt) library(maptools) library(rgdal) library(tidyr) library(RColorBrewer) library(spdep) library(plyr) library(tmap)
Preparação dos dados
rr # Importando Dados districts <- readOGR(dsn = ./LAPD_Reporting_Districts.shp)
OGR data source with driver: ESRI Shapefile
Source: \E:\Analises R\Crime-em-Los-Angeles\Codigo R\LAPD_Reporting_Districts.shp\, layer: \LAPD_Reporting_Districts\
with 1135 features
It has 7 fields
Integer64 fields read as strings: OBJECTID REPDIST PREC
rr crime = read.csv(../Dados/Crime_Data_2010_2017.csv)
head(crime,5) r head(districts@data, 5)
Observando rapidamente os dados, podemos ver que o shapefile é composto de 1135 recursos diferentes. Isto corresponde ao distrito declarante em LA: crime\(Reporting.District and districts@data\)REPDIST.
Usando as colunas comuns, podemos tentar mesclar os dados. Primeiro precisamos somar o número de crimes em cada distrito.
rr w <- table(crime\(Reporting.District) rep.dis <- as.data.frame(w) length(unique(rep.dis\)Var1))
[1] 1280
rr head(rep.dis, 5)
Como podemos ver acima, o número de valores únicos não é igual ao número de recursos no shapefile, isto representa 0 crimes cometidos nesses distritos. Portanto, ao entrar, mantemos essas colunas usando “all.x = TRUE”. Isso significa que mantemos todas as linhas de dados no shapefile. Estes retornam resultados de NA, por padrão, então mudamos isso com a segunda linha de código.
rr districts@data <- merge(districts@data, rep.dis, by.x = , by.y = 1, all.x = TRUE) districts\(Freq[is.na(districts\)Freq)] <- 0 length(districts$Freq)
[1] 1135
Plotando Freqüência Criminal
rr var <- districts@data[,] breaks <- classIntervals(var, n = 9, style = ) my_colours <- rev(brewer.pal(9, )) plot(districts, col = my_colours[findInterval(var, breaks$brks, all.inside = TRUE)],
axes = FALSE, border = NA) legend(x = -118.7, y = 34, legend = leglabs(breaks$brks), fill = my_colours, bty = , cex = 0.6)

Uma rápida visão geral da trama mostra a maioria dos distritos com menores contagens de crimes denunciados. Existem casos esporádicos de altas contagens, especialmente em áreas ao norte, o que poderia sugerir uma autocorrelação espacial próxima a zero, representando a aleatoriedade na distribuição espacial dos dados.
Uma medida melhor seria as taxas de criminalidade, no entanto, a população por distritos reportados não está disponível.
Autocorrelação Espacial
Em vez de especular usando o gráfico, vamos tentar quantificar a correlação. A autocorrelação espacial mede como a distância influencia uma variável específica, neste caso a freqüência do crime em um distrito.
Usando a primeira lei de geografia de Tobler, esperamos que a maioria dos fenômenos geográficos exerça uma autocorrelação espacial de algum tipo. Este é frequentemente o caso em dados com fatores humanos, já que pessoas de características similares tendem a residir em vizinhanças semelhantes devido a uma variedade de razões, incluindo preços de casas, proximidade a locais de trabalho e fatores culturais.
A autocorrelação espacial pode ser representada de duas maneiras: global ou localmente. O modelo global cria uma medida individual representando todo o conjunto de dados, enquanto os modelos locais nos permitem explorar o agrupamento espacial em toda a área de LA.
Primeiro temos que atribuir neibourghs a cada um dos distritos. Existem 2 métodos para fazer isso: Rook ou Queen. Podemos traçar as ligações entre os distritos vizinhos para visualizar sua distribuição no espaço.
rr neighbours <- poly2nb(districts) neighbours
Neighbour list object:
Number of regions: 1135
Number of nonzero links: 7080
Percentage nonzero weights: 0.5495934
Average number of links: 6.237885
rr plot(districts, border = ‘lightgrey’) plot(neighbours, coordinates(districts), add=TRUE, col=‘red’)

rr neighbours2 <- poly2nb(districts, queen = FALSE) neighbours2
Neighbour list object:
Number of regions: 1135
Number of nonzero links: 5394
Percentage nonzero weights: 0.4187157
Average number of links: 4.752423
rr plot(districts, border = ‘lightgrey’) plot(neighbours, coordinates(districts), add=TRUE, col=‘blue’) r plot(neighbours2, coordinates(districts), add=TRUE, col=‘red’)

Podemos ver que o segundo método (Rook) retorna muito menos links e podemos interpretar visualmente a diferença.
Autocorrelação Espacial Global
Agora que temos vizinhos, precisamos convertê-los.
Então podemos executar o teste de um moran. Isso cria um valor de correlação entre -1 e 1, a distribuição espacial desses valores é vista na figura da Introdução. 1 representa autocorrelação espacial positiva perfeita, 0 mostra que os dados são distribuídos aleatoriamente e -1 é autocorrelação espacial negativa.
rr listw <- nb2listw(neighbours) listw
Characteristics of weights list object:
Neighbour list object:
Number of regions: 1135
Number of nonzero links: 7080
Percentage nonzero weights: 0.5495934
Average number of links: 6.237885
Weights style: W
Weights constants summary:
rr moran.test(districts$Freq, listw)
Moran I test under randomisation
data: districts$Freq
weights: listw
Moran I statistic standard deviate = 4.97, p-value = 3.348e-07
alternative hypothesis: greater
sample estimates:
Moran I statistic Expectation Variance
0.0853613741 -0.0008818342 0.0003011199
A estatística Global Moran I é de 0,085, mostrando que a frequência de crimes em cada distrito é distribuída de forma significativamente aleatória. No entanto, vamos dar uma olhada nisso e ver se a autocorrelação espacial local retorna um resultado similar.
Autocorrelação Espacial Local
Em primeiro lugar, criamos um gráfico moran olhando para cada um dos valores plotados em relação aos seus valores espacialmente defasados. Explora a relação entre os dados e seus vizinhos.
rr moran <- moran.plot(districts$Freq, listw = nb2listw(neighbours2, style = ))

A partir do gráfico de dispersão, sugere potencialmente que a frequência dos crimes de cada distrito seja aleatória. Vamos tentar mapeá-lo.
rr local <- localmoran(x = districts$Freq, listw = nb2listw(neighbours2, style = )) moran.map <- cbind(districts, local) tm_shape(moran.map) + tm_fill(col = , style = , title = moran statistic)

Um valor positivo indica que o distrito é cercado por distritos de valor semelhante.
Do mapa, podemos ver que, em grande parte, nos distritos de LA, não há relação entre o número de crimes de um distrito e o de um distrito vizinho. No entanto, podemos ver alguns grupos de alta similaridade nos distritos do norte. Embora, não seja possível interpretar se estes são grupos de alta contagem de crimes ou baixos, apenas que são semelhantes. Então, nós conduzimos um mapa de cluster LISA.
LISA
rr quadrant <- vector(mode=,length=nrow(local))
Constrói um quadrante de dados
quadrant[m.crime >0 & m.local>0] <- 4
quadrant[m.crime <0 & m.local<0] <- 1
quadrant[m.crime <0 & m.local>0] <- 2 quadrant[m.crime >0 & m.local<0] <- 3 quadrant[local[,5]>signif] <- 0
brks <- c(0,1,2,3,4) colors <- c(,,rgb(0,0,1,alpha=0.4),rgb(1,0,0,alpha=0.4),)
plot(districts,border=,col=colors[findInterval(quadrant,brks,all.inside=FALSE)]) box() r legend(x = -118.7, y = 34,legend=c(,-low,-high,-low,-high), fill=colors,bty=)

Conclusão
Como podemos ver no mapa, que o aglomerado, identificado no mapa anterior do moran, eram distritos de altas contagens de crimes relatados cercados por outros distritos de altos relatórios de crimes. Surpreendentemente, 2 das variáveis do cluster não estão presentes: distritos de baixa frequência do crime cercados por distritos similares de baixa incidência de crimes (azul escuro) e distritos de alta criminalidade cercados por distritos de baixa frequência criminal.
LS0tDQp0aXRsZTogIkF1dG9jb3JyZWxhw6fDo28gRXNwYWNpYWwgZG8gQ3JpbWUgZGUgTG9zIEFuZ2VsZXMiDQphdXRob3I6ICJFcml2YW5kbyBTZW5hIChDb20gYWRhcHRhw6fDtWVzIGRvIG9yaWdpbmFsIFIgTm90ZWJvb2sgZGUgQW1iYXJpc2ggR2FuZ3VseSkiDQplbWFpbDogImVyaXZhbmRvc2VuYUBnbWFpbC5jb20iDQpkYXRlOiAiMjIgZGUgbWFpbyBkZSAyMDE5Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiAgIA0KIyMgSW50cm9kdcOnw6NvDQoNCkVzdGEgYW7DoWxpc2UgYnVzY2EgaW52ZXN0aWdhciB1bSBtw6l0b2RvIGRlIGPDoWxjdWxvIGRlIGNvcnJlbGHDp8OjbyBlc3BhY2lhbCBlbSBSLiBDb25zaWRlcmFyZW1vcyBhcyBlc3RhdMOtc3RpY2FzIGRlIGF1dG9jb3JyZWxhw6fDo28gZXNwYWNpYWwgZ2xvYmFsIGUgY29tbyBpZGVudGlmaWNhciBhZ3J1cGFtZW50b3MgZXNwYWNpYWlzIGVtIHRvZGEgYSBub3NzYSDDoXJlYSBkZSBlc3R1ZG8uDQoNCkEgYmFzZSBkZXN0ZSB0cmFiYWxobyDDqSBhIFByaW1laXJhIExlaSBkYSBHZW9ncmFmaWEgZGUgVG9ibGVyOiAidHVkbyBlc3TDoSByZWxhY2lvbmFkbyBhIHR1ZG8gbWFpcywgbWFzIGFzIGNvaXNhcyBwcsOzeGltYXMgZXN0w6NvIG1haXMgcmVsYWNpb25hZGFzIGRvIHF1ZSBhcyBjb2lzYXMgZGlzdGFudGVzIi4NCg0KQXNzaW0sIHVzYW5kbyBvIGNvbmp1bnRvIGRlIGRhZG9zKFtEYWRvcyBkZSBDcmltZSBQb2zDrWNpYSBkZSBMb3MgQW5nZWxlc10oaHR0cHM6Ly9kYXRhLmxhY2l0eS5vcmcvQS1TYWZlLUNpdHkvQ3JpbWUtRGF0YS1mcm9tLTIwMTAtdG8tUHJlc2VudC95OHRyLTdraHEpe3RhcmdldD0iX3RvcCJ9KSwgdmVyZW1vcyBzZSBvIGNyaW1lIGVtIExvcyBBbmdlbGVzKFtBbmFsaXNhZG8gbmEgQ29tdW5pZGFkZSBLYWdnbGVdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vY2l0eW9mTEEvY3JpbWUtaW4tbG9zLWFuZ2VsZXMpe3RhcmdldD0iX3RvcCJ9KSDDqSBlc3BhY2lhbG1lbnRlIGF1dG9jb3JyZWxhY2lvbmFkbyBlIGlkZW50aWZpY2Ftb3Mgb3MgY2x1c2VycyB1c2FuZG8gbyBMSVNBIChMb2NhbCBNZWFzdXJlIG9mIFNwYXRpYWwgQXNzb2NpYXRpb24pLiAgDQoNCiMjIyMgQXV0b2NvcnJlbGHDp8OjbyBFc3BhY2lhbA0KYGBge3IgaW1hZ2VtLCBlY2hvID0gVFJVRSwgb3V0LndpZHRoID0gJzEwMCUnfQ0KDQojIEV4aWJpbmRvIGltYWdlbQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4vU3BhdGlhbF9BdXRvY29ycmVsYXRpb24uanBnIikNCg0KYGBgDQoNCiMjIyMgUHJlcGFyYW5kbyBvIGFtYmllbnRlDQpgYGB7ciBjb25maWd1cmFjYW8sIGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0V9DQojIFNldGFuZG8gaWRpb21hIGUgbG9jYWwgZGEgcGFzdGEgZGUgdHJhYmFsaG8NClN5cy5zZXRsb2NhbGUoIkxDX0FMTCIsICJQb3J0dWd1ZXNlX0JyYXppbC4xMjUyIikNCnNldHdkKCJFOi9PdXRyYXMgQW5hbGlzZXMgUi9DcmltZS1lbS1Mb3MtQW5nZWxlcyIpDQogDQojIEluc3RhbGFuZG8gcGFjb3Rlcw0KcGFjb3RlcyA8LSBjKCd0aWR5dmVyc2UnLCAnY2xhc3NJbnQnLCAnbWFwdG9vbHMnLCAncmdkYWwnLCAnUkNvbG9yQnJld2VyJywgJ3NwZGVwJywgJ3RtYXAnKQ0KbG9jYWxfbGliIDwtICJDOi9QUk9HUkF+MS9SL1ItMy42LjAvbGlicmFyeSINCm5ldy5wYWNrYWdlcyA8LSBwYWNvdGVzWyEocGFjb3RlcyAlaW4lIGluc3RhbGxlZC5wYWNrYWdlcygpWywiUGFja2FnZSJdKV0gDQppZihsZW5ndGgobmV3LnBhY2thZ2VzKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKHBhY290ZXMsIGRlcCA9IFRSVUUpIA0KfQ0KIA0KIyBJbXBvcnRhbmRvIGJpYmxpb3RlY2FzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoY2xhc3NJbnQpDQpsaWJyYXJ5KG1hcHRvb2xzKQ0KbGlicmFyeShyZ2RhbCkNCmxpYnJhcnkodGlkeXIpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkoc3BkZXApDQpsaWJyYXJ5KHBseXIpDQpsaWJyYXJ5KHRtYXApDQpgYGANCg0KIyMjIyBQcmVwYXJhw6fDo28gZG9zIGRhZG9zDQpgYGB7ciBkYWRvcywgZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRX0NCiMgSW1wb3J0YW5kbyBEYWRvcw0KZGlzdHJpY3RzIDwtIHJlYWRPR1IoZHNuID0gIi4vTEFQRF9SZXBvcnRpbmdfRGlzdHJpY3RzLnNocCIpDQpjcmltZSA9IHJlYWQuY3N2KCIuLi9EYWRvcy9DcmltZV9EYXRhXzIwMTBfMjAxNy5jc3YiKQ0KIA0KaGVhZChjcmltZSw1KQ0KaGVhZChkaXN0cmljdHNAZGF0YSwgNSkNCmBgYA0KDQpPYnNlcnZhbmRvIHJhcGlkYW1lbnRlIG9zIGRhZG9zLCBwb2RlbW9zIHZlciBxdWUgbyBzaGFwZWZpbGUgw6kgY29tcG9zdG8gZGUgMTEzNSByZWN1cnNvcyBkaWZlcmVudGVzLiBJc3RvIGNvcnJlc3BvbmRlIGFvIGRpc3RyaXRvIGRlY2xhcmFudGUgZW0gTEE6IGNyaW1lJFJlcG9ydGluZy5EaXN0cmljdCBhbmQgZGlzdHJpY3RzQGRhdGEkUkVQRElTVC4gIA0KDQpVc2FuZG8gYXMgY29sdW5hcyBjb211bnMsIHBvZGVtb3MgdGVudGFyIG1lc2NsYXIgb3MgZGFkb3MuIFByaW1laXJvIHByZWNpc2Ftb3Mgc29tYXIgbyBuw7ptZXJvIGRlIGNyaW1lcyBlbSBjYWRhIGRpc3RyaXRvLg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFfQ0KdyA8LSB0YWJsZShjcmltZSRSZXBvcnRpbmcuRGlzdHJpY3QpDQpyZXAuZGlzIDwtIGFzLmRhdGEuZnJhbWUodykNCmxlbmd0aCh1bmlxdWUocmVwLmRpcyRWYXIxKSkNCmhlYWQocmVwLmRpcywgNSkNCg0KYGBgDQoNCkNvbW8gcG9kZW1vcyB2ZXIgYWNpbWEsIG8gbsO6bWVybyBkZSB2YWxvcmVzIMO6bmljb3MgbsOjbyDDqSBpZ3VhbCBhbyBuw7ptZXJvIGRlIHJlY3Vyc29zIG5vIHNoYXBlZmlsZSwgaXN0byByZXByZXNlbnRhIDAgY3JpbWVzIGNvbWV0aWRvcyBuZXNzZXMgZGlzdHJpdG9zLiBQb3J0YW50bywgYW8gZW50cmFyLCBtYW50ZW1vcyBlc3NhcyBjb2x1bmFzIHVzYW5kbyAiYWxsLnggPSBUUlVFIi4gSXNzbyBzaWduaWZpY2EgcXVlIG1hbnRlbW9zIHRvZGFzIGFzIGxpbmhhcyBkZSBkYWRvcyBubyBzaGFwZWZpbGUuIEVzdGVzIHJldG9ybmFtIHJlc3VsdGFkb3MgZGUgTkEsIHBvciBwYWRyw6NvLCBlbnTDo28gbXVkYW1vcyBpc3NvIGNvbSBhIHNlZ3VuZGEgbGluaGEgZGUgY8OzZGlnby4NCg0KYGBge3IgZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRX0NCmRpc3RyaWN0c0BkYXRhIDwtIG1lcmdlKGRpc3RyaWN0c0BkYXRhLCByZXAuZGlzLCBieS54ID0gIlJFUERJU1QiLCBieS55ID0gIlZhcjEiLCBhbGwueCA9IFRSVUUpDQpkaXN0cmljdHMkRnJlcVtpcy5uYShkaXN0cmljdHMkRnJlcSldIDwtIDANCmxlbmd0aChkaXN0cmljdHMkRnJlcSkNCmBgYA0KDQojIyMgUGxvdGFuZG8gRnJlccO8w6puY2lhIENyaW1pbmFsDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0V9DQp2YXIgPC0gZGlzdHJpY3RzQGRhdGFbLCJGcmVxIl0NCmJyZWFrcyA8LSBjbGFzc0ludGVydmFscyh2YXIsIG4gPSA5LCBzdHlsZSA9ICJmaXNoZXIiKQ0KbXlfY29sb3VycyA8LSByZXYoYnJld2VyLnBhbCg5LCAiUmRCdSIpKQ0KcGxvdChkaXN0cmljdHMsIGNvbCA9IG15X2NvbG91cnNbZmluZEludGVydmFsKHZhciwgYnJlYWtzJGJya3MsIGFsbC5pbnNpZGUgPSBUUlVFKV0sICAgDQogICAgICAgYXhlcyA9IEZBTFNFLCBib3JkZXIgPSBOQSkNCmxlZ2VuZCh4ID0gLTExOC43LCB5ID0gMzQsIGxlZ2VuZCA9IGxlZ2xhYnMoYnJlYWtzJGJya3MpLCBmaWxsID0gbXlfY29sb3VycywgYnR5ID0gIm4iLCBjZXggPSAwLjYpDQpgYGANCg0KVW1hIHLDoXBpZGEgdmlzw6NvIGdlcmFsIGRhIHRyYW1hIG1vc3RyYSBhIG1haW9yaWEgZG9zIGRpc3RyaXRvcyBjb20gbWVub3JlcyBjb250YWdlbnMgZGUgY3JpbWVzIGRlbnVuY2lhZG9zLiBFeGlzdGVtIGNhc29zIGVzcG9yw6FkaWNvcyBkZSBhbHRhcyBjb250YWdlbnMsIGVzcGVjaWFsbWVudGUgZW0gw6FyZWFzIGFvIG5vcnRlLCBvIHF1ZSBwb2RlcmlhIHN1Z2VyaXIgdW1hIGF1dG9jb3JyZWxhw6fDo28gZXNwYWNpYWwgcHLDs3hpbWEgYSB6ZXJvLCByZXByZXNlbnRhbmRvIGEgYWxlYXRvcmllZGFkZSBuYSBkaXN0cmlidWnDp8OjbyBlc3BhY2lhbCBkb3MgZGFkb3MuDQoNClVtYSBtZWRpZGEgbWVsaG9yIHNlcmlhIGFzIHRheGFzIGRlIGNyaW1pbmFsaWRhZGUsIG5vIGVudGFudG8sIGEgcG9wdWxhw6fDo28gcG9yIGRpc3RyaXRvcyByZXBvcnRhZG9zIG7Do28gZXN0w6EgZGlzcG9uw612ZWwuDQoNCiMjIyBBdXRvY29ycmVsYcOnw6NvIEVzcGFjaWFsDQpFbSB2ZXogZGUgZXNwZWN1bGFyIHVzYW5kbyBvIGdyw6FmaWNvLCB2YW1vcyB0ZW50YXIgcXVhbnRpZmljYXIgYSBjb3JyZWxhw6fDo28uIEEgYXV0b2NvcnJlbGHDp8OjbyBlc3BhY2lhbCBtZWRlIGNvbW8gYSBkaXN0w6JuY2lhIGluZmx1ZW5jaWEgdW1hIHZhcmnDoXZlbCBlc3BlY8OtZmljYSwgbmVzdGUgY2FzbyBhIGZyZXHDvMOqbmNpYSBkbyBjcmltZSBlbSB1bSBkaXN0cml0by4gIA0KDQpVc2FuZG8gYSBwcmltZWlyYSBsZWkgZGUgZ2VvZ3JhZmlhIGRlIFRvYmxlciwgZXNwZXJhbW9zIHF1ZSBhIG1haW9yaWEgZG9zIGZlbsO0bWVub3MgZ2VvZ3LDoWZpY29zIGV4ZXLDp2EgdW1hIGF1dG9jb3JyZWxhw6fDo28gZXNwYWNpYWwgZGUgYWxndW0gdGlwby4gRXN0ZSDDqSBmcmVxdWVudGVtZW50ZSBvIGNhc28gZW0gZGFkb3MgY29tIGZhdG9yZXMgaHVtYW5vcywgasOhIHF1ZSBwZXNzb2FzIGRlIGNhcmFjdGVyw61zdGljYXMgc2ltaWxhcmVzIHRlbmRlbSBhIHJlc2lkaXIgZW0gdml6aW5oYW7Dp2FzIHNlbWVsaGFudGVzIGRldmlkbyBhIHVtYSB2YXJpZWRhZGUgZGUgcmF6w7VlcywgaW5jbHVpbmRvIHByZcOnb3MgZGUgY2FzYXMsIHByb3hpbWlkYWRlIGEgbG9jYWlzIGRlIHRyYWJhbGhvIGUgZmF0b3JlcyBjdWx0dXJhaXMuICANCg0KQSBhdXRvY29ycmVsYcOnw6NvIGVzcGFjaWFsIHBvZGUgc2VyIHJlcHJlc2VudGFkYSBkZSBkdWFzIG1hbmVpcmFzOiBnbG9iYWwgb3UgbG9jYWxtZW50ZS4gTyBtb2RlbG8gZ2xvYmFsIGNyaWEgdW1hIG1lZGlkYSBpbmRpdmlkdWFsIHJlcHJlc2VudGFuZG8gdG9kbyBvIGNvbmp1bnRvIGRlIGRhZG9zLCBlbnF1YW50byBvcyBtb2RlbG9zIGxvY2FpcyBub3MgcGVybWl0ZW0gZXhwbG9yYXIgbyBhZ3J1cGFtZW50byBlc3BhY2lhbCBlbSB0b2RhIGEgw6FyZWEgZGUgTEEuICANCg0KUHJpbWVpcm8gdGVtb3MgcXVlIGF0cmlidWlyIG5laWJvdXJnaHMgYSBjYWRhIHVtIGRvcyBkaXN0cml0b3MuIEV4aXN0ZW0gMiBtw6l0b2RvcyBwYXJhIGZhemVyIGlzc286IFJvb2sgb3UgUXVlZW4uIFBvZGVtb3MgdHJhw6dhciBhcyBsaWdhw6fDtWVzIGVudHJlIG9zIGRpc3RyaXRvcyB2aXppbmhvcyBwYXJhIHZpc3VhbGl6YXIgc3VhIGRpc3RyaWJ1acOnw6NvIG5vIGVzcGHDp28uDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0V9DQpuZWlnaGJvdXJzIDwtIHBvbHkybmIoZGlzdHJpY3RzKQ0KbmVpZ2hib3Vycw0KcGxvdChkaXN0cmljdHMsIGJvcmRlciA9ICdsaWdodGdyZXknKQ0KcGxvdChuZWlnaGJvdXJzLCBjb29yZGluYXRlcyhkaXN0cmljdHMpLCBhZGQ9VFJVRSwgY29sPSdyZWQnKQ0KYGBgDQoNCg0KYGBge3IgZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRX0NCm5laWdoYm91cnMyIDwtIHBvbHkybmIoZGlzdHJpY3RzLCBxdWVlbiA9IEZBTFNFKQ0KbmVpZ2hib3VyczINCnBsb3QoZGlzdHJpY3RzLCBib3JkZXIgPSAnbGlnaHRncmV5JykNCnBsb3QobmVpZ2hib3VycywgY29vcmRpbmF0ZXMoZGlzdHJpY3RzKSwgYWRkPVRSVUUsIGNvbD0nYmx1ZScpDQpwbG90KG5laWdoYm91cnMyLCBjb29yZGluYXRlcyhkaXN0cmljdHMpLCBhZGQ9VFJVRSwgY29sPSdyZWQnKQ0KYGBgDQoNClBvZGVtb3MgdmVyIHF1ZSBvIHNlZ3VuZG8gbcOpdG9kbyAoUm9vaykgcmV0b3JuYSBtdWl0byBtZW5vcyBsaW5rcyBlIHBvZGVtb3MgaW50ZXJwcmV0YXIgdmlzdWFsbWVudGUgYSBkaWZlcmVuw6dhLiAgDQoNCiMjIyBBdXRvY29ycmVsYcOnw6NvIEVzcGFjaWFsIEdsb2JhbA0KDQpBZ29yYSBxdWUgdGVtb3Mgdml6aW5ob3MsIHByZWNpc2Ftb3MgY29udmVydMOqLWxvcy4NCg0KRW50w6NvIHBvZGVtb3MgZXhlY3V0YXIgbyB0ZXN0ZSBkZSB1bSBtb3Jhbi4gSXNzbyBjcmlhIHVtIHZhbG9yIGRlIGNvcnJlbGHDp8OjbyBlbnRyZSAtMSBlIDEsIGEgZGlzdHJpYnVpw6fDo28gZXNwYWNpYWwgZGVzc2VzIHZhbG9yZXMgw6kgdmlzdGEgbmEgZmlndXJhIGRhIEludHJvZHXDp8Ojby4gMSByZXByZXNlbnRhIGF1dG9jb3JyZWxhw6fDo28gZXNwYWNpYWwgcG9zaXRpdmEgcGVyZmVpdGEsIDAgbW9zdHJhIHF1ZSBvcyBkYWRvcyBzw6NvIGRpc3RyaWJ1w61kb3MgYWxlYXRvcmlhbWVudGUgZSAtMSDDqSBhdXRvY29ycmVsYcOnw6NvIGVzcGFjaWFsIG5lZ2F0aXZhLg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFfQ0KDQpsaXN0dyA8LSBuYjJsaXN0dyhuZWlnaGJvdXJzKQ0KbGlzdHcNCm1vcmFuLnRlc3QoZGlzdHJpY3RzJEZyZXEsIGxpc3R3KQ0KDQpgYGANCg0KQSBlc3RhdMOtc3RpY2EgR2xvYmFsIE1vcmFuIEkgw6kgZGUgMCwwODUsIG1vc3RyYW5kbyBxdWUgYSBmcmVxdcOqbmNpYSBkZSBjcmltZXMgZW0gY2FkYSBkaXN0cml0byDDqSBkaXN0cmlidcOtZGEgZGUgZm9ybWEgc2lnbmlmaWNhdGl2YW1lbnRlIGFsZWF0w7NyaWEuIE5vIGVudGFudG8sIHZhbW9zIGRhciB1bWEgb2xoYWRhIG5pc3NvIGUgdmVyIHNlIGEgYXV0b2NvcnJlbGHDp8OjbyBlc3BhY2lhbCBsb2NhbCByZXRvcm5hIHVtIHJlc3VsdGFkbyBzaW1pbGFyLiAgDQoNCiMjIyBBdXRvY29ycmVsYcOnw6NvIEVzcGFjaWFsIExvY2FsDQpFbSBwcmltZWlybyBsdWdhciwgY3JpYW1vcyB1bSBncsOhZmljbyBtb3JhbiBvbGhhbmRvIHBhcmEgY2FkYSB1bSBkb3MgdmFsb3JlcyBwbG90YWRvcyBlbSByZWxhw6fDo28gYW9zIHNldXMgdmFsb3JlcyBlc3BhY2lhbG1lbnRlIGRlZmFzYWRvcy4gRXhwbG9yYSBhIHJlbGHDp8OjbyBlbnRyZSBvcyBkYWRvcyBlIHNldXMgdml6aW5ob3MuDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0V9DQptb3JhbiA8LSBtb3Jhbi5wbG90KGRpc3RyaWN0cyRGcmVxLCBsaXN0dyA9IG5iMmxpc3R3KG5laWdoYm91cnMyLCBzdHlsZSA9ICJXIikpDQpgYGANCg0KQSBwYXJ0aXIgZG8gZ3LDoWZpY28gZGUgZGlzcGVyc8Ojbywgc3VnZXJlIHBvdGVuY2lhbG1lbnRlIHF1ZSBhIGZyZXF1w6puY2lhIGRvcyBjcmltZXMgZGUgY2FkYSBkaXN0cml0byBzZWphIGFsZWF0w7NyaWEuIFZhbW9zIHRlbnRhciBtYXBlw6EtbG8uDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0V9DQpsb2NhbCA8LSBsb2NhbG1vcmFuKHggPSBkaXN0cmljdHMkRnJlcSwgbGlzdHcgPSBuYjJsaXN0dyhuZWlnaGJvdXJzMiwgc3R5bGUgPSAiVyIpKQ0KbW9yYW4ubWFwIDwtIGNiaW5kKGRpc3RyaWN0cywgbG9jYWwpDQp0bV9zaGFwZShtb3Jhbi5tYXApICsgdG1fZmlsbChjb2wgPSAiSWkiLCBzdHlsZSA9ICJxdWFudGlsZSIsIHRpdGxlID0gImxvY2FsIG1vcmFuIHN0YXRpc3RpYyIpDQpgYGANCg0KVW0gdmFsb3IgcG9zaXRpdm8gaW5kaWNhIHF1ZSBvIGRpc3RyaXRvIMOpIGNlcmNhZG8gcG9yIGRpc3RyaXRvcyBkZSB2YWxvciBzZW1lbGhhbnRlLg0KDQpEbyBtYXBhLCBwb2RlbW9zIHZlciBxdWUsIGVtIGdyYW5kZSBwYXJ0ZSwgbm9zIGRpc3RyaXRvcyBkZSBMQSwgbsOjbyBow6EgcmVsYcOnw6NvIGVudHJlIG8gbsO6bWVybyBkZSBjcmltZXMgZGUgdW0gZGlzdHJpdG8gZSBvIGRlIHVtIGRpc3RyaXRvIHZpemluaG8uIE5vIGVudGFudG8sIHBvZGVtb3MgdmVyIGFsZ3VucyBncnVwb3MgZGUgYWx0YSBzaW1pbGFyaWRhZGUgbm9zIGRpc3RyaXRvcyBkbyBub3J0ZS4gRW1ib3JhLCBuw6NvIHNlamEgcG9zc8OtdmVsIGludGVycHJldGFyIHNlIGVzdGVzIHPDo28gZ3J1cG9zIGRlIGFsdGEgY29udGFnZW0gZGUgY3JpbWVzIG91IGJhaXhvcywgYXBlbmFzIHF1ZSBzw6NvIHNlbWVsaGFudGVzLiBFbnTDo28sIG7Ds3MgY29uZHV6aW1vcyB1bSBtYXBhIGRlIGNsdXN0ZXIgTElTQS4NCg0KIyMjIExJU0ENCg0KYGBge3IgZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRX0NCnF1YWRyYW50IDwtIHZlY3Rvcihtb2RlPSJudW1lcmljIixsZW5ndGg9bnJvdyhsb2NhbCkpDQogDQojIENlbnRyYWxpemEgYSB2YXJpw6F2ZWwgZGUgaW50ZXJlc3NlIGVtIHRvcm5vIGRlIHN1YSBtw6lkaWENCm0uY3JpbWUgPC0gZGlzdHJpY3RzJEZyZXEgLSBtZWFuKGRpc3RyaWN0cyRGcmVxKSAgICAgDQogDQojIENlbnRyYWxpemEgTW9yYW7CtHMgbG9jYWwgZW0gdG9ybm8gZGEgbcOpZGlhDQptLmxvY2FsIDwtIGxvY2FsWywxXSAtIG1lYW4obG9jYWxbLDFdKSAgICANCiANCiMgTGltaWFyIGRlIHNpZ25pZmljw6JuY2lhDQpzaWduaWYgPC0gMC4xIA0KIA0KIyBDb25zdHLDs2kgdW0gcXVhZHJhbnRlIGRlIGRhZG9zDQpxdWFkcmFudFttLmNyaW1lID4wICYgbS5sb2NhbD4wXSA8LSA0ICANCnF1YWRyYW50W20uY3JpbWUgPDAgJiBtLmxvY2FsPDBdIDwtIDEgICAgICANCnF1YWRyYW50W20uY3JpbWUgPDAgJiBtLmxvY2FsPjBdIDwtIDINCnF1YWRyYW50W20uY3JpbWUgPjAgJiBtLmxvY2FsPDBdIDwtIDMNCnF1YWRyYW50W2xvY2FsWyw1XT5zaWduaWZdIDwtIDAgICANCiANCmJya3MgPC0gYygwLDEsMiwzLDQpDQpjb2xvcnMgPC0gYygid2hpdGUiLCJibHVlIixyZ2IoMCwwLDEsYWxwaGE9MC40KSxyZ2IoMSwwLDAsYWxwaGE9MC40KSwicmVkIikNCiANCnBsb3QoZGlzdHJpY3RzLGJvcmRlcj0ibGlnaHRncmF5Iixjb2w9Y29sb3JzW2ZpbmRJbnRlcnZhbChxdWFkcmFudCxicmtzLGFsbC5pbnNpZGU9RkFMU0UpXSkNCmJveCgpDQpsZWdlbmQoeCA9IC0xMTguNywgeSA9IDM0LGxlZ2VuZD1jKCJpbnNpZ25pZmljYW50IiwibG93LWxvdyIsImxvdy1oaWdoIiwiaGlnaC1sb3ciLCJoaWdoLWhpZ2giKSwNCiAgICAgICBmaWxsPWNvbG9ycyxidHk9Im4iKQ0KYGBgDQoNCiMjIENvbmNsdXPDo28NCg0KQ29tbyBwb2RlbW9zIHZlciBubyBtYXBhLCBxdWUgbyBhZ2xvbWVyYWRvLCBpZGVudGlmaWNhZG8gbm8gbWFwYSBhbnRlcmlvciBkbyBtb3JhbiwgZXJhbSBkaXN0cml0b3MgZGUgYWx0YXMgY29udGFnZW5zIGRlIGNyaW1lcyByZWxhdGFkb3MgY2VyY2Fkb3MgcG9yIG91dHJvcyBkaXN0cml0b3MgZGUgYWx0b3MgcmVsYXTDs3Jpb3MgZGUgY3JpbWVzLiBTdXJwcmVlbmRlbnRlbWVudGUsIDIgZGFzIHZhcmnDoXZlaXMgZG8gY2x1c3RlciBuw6NvIGVzdMOjbyBwcmVzZW50ZXM6IGRpc3RyaXRvcyBkZSBiYWl4YSBmcmVxdcOqbmNpYSBkbyBjcmltZSBjZXJjYWRvcyBwb3IgZGlzdHJpdG9zIHNpbWlsYXJlcyBkZSBiYWl4YSBpbmNpZMOqbmNpYSBkZSBjcmltZXMgKGF6dWwgZXNjdXJvKSBlIGRpc3RyaXRvcyBkZSBhbHRhIGNyaW1pbmFsaWRhZGUgY2VyY2Fkb3MgcG9yIGRpc3RyaXRvcyBkZSBiYWl4YSBmcmVxdcOqbmNpYSBjcmltaW5hbC4gDQoNCiMjIERpc3BvbmliaWxpZGFkZSBkb3MgZGFkb3MNCk8gY29uanVudG8gZGUgZGFkb3MgYmVtIGNvbW8gbyBjw7NkaWdvIFIgZSBhcnF1aXZvcyBhdXhpbGlhcmVzIHV0aWxpemFkb3MgbmVzdGEgYW7DoWxpc2UgcG9kZW0gc2VyIGVuY29udHJhZG9zIGVtOiBbaHR0cHM6Ly9naXRodWIuY29tL2VyaXZhbmRvcmFtb3MvQ3JpbWUtZW0tTG9zLUFuZ2VsZXNdKGh0dHBzOi8vZ2l0aHViLmNvbS9lcml2YW5kb3JhbW9zL0NyaW1lLWVtLUxvcy1BbmdlbGVzKXt0YXJnZXQ9Il90b3AifQ0KDQojIyBSZWZlcsOqbmNpYXMNCg0KQW1iYXJpc2ggR2FuZ3VseS4gKipMaXR0bGUgQm9vayBvbiBEYXRhIFZpc3VhbGl6YXRpb24gYW5kIE1vZGVsbGluZyoqLiBEaXNwb27DrXZlbCBlbTogPFtodHRwczovL2FtYmFyaXNoZy5naXRodWIuaW8vYm9va3MvTGl0dGxlQm9va0RhdGFWaXpdKGh0dHBzOi8vYW1iYXJpc2hnLmdpdGh1Yi5pby9ib29rcy9MaXR0bGVCb29rRGF0YVZpeil7dGFyZ2V0PSJfdG9wIn0+IEFjZXNzbyBlbTogMjIgbWFpLiAyMDE5LiANCg==